<?php

namespace app\logics;

use app\collections\Collection;
use app\libs\Application;
use app\tools\Table;
use app\traits\ErrorCode;
use Phalcon\Http\Request;

class User extends \Phalcon\Di\Injectable
{
    use ErrorCode;

    /**
     * @param $request \Phalcon\Http\Request|\Phalcon\Http\RequestInterface
     * @return boolean | \app\models\User
     */
    public static function login(&$request)
    {
        $mobile = $request->getPost('mobile');
        $password = $request->getPost('password');
        $user = self::verifyLoginPassword($mobile, $password);
        if (!$user) {
            return false;
        }
        $oldToken = $user->last_login_token;
        $cache = $user->getCache();
        if (!empty($oldToken)) {
            $cache->delete($oldToken);
        }
        $newToken = bin2hex($user->getRandom()->bytes(16));
        $loginIp = $request->getClientAddress();
        $cache->save($newToken, [
            'uid' => $user->id,
            'open_id' => $user->open_id,
            'nickname' => $user->nickname,
            'icon' => $user->icon,
            'mobile' => $user->mobile,
            'login_ip' => $loginIp
        ], 3600 * 24);
        $user->last_login_token = $newToken;
        $user->last_login_ip = $loginIp;
        $user->last_login_at = time();
        $data = [
            'last_login_token' => $newToken,
            'last_login_ip' => $loginIp,
            'last_login_at' => $user->last_login_at
        ];
//        $user->update($data);
        $user::modelUpdate($user->getSource(), ['id' => $user->id], $data);
        self::userLoginLog($user, $request);
        return $user;
    }

    public static function appLogin($mobile, $password, $appid)
    {
        $user = self::verifyLoginPassword($mobile, $password);
        if (!$user) {
            return false;
        }
        //记录app的登录日志 暂时不记
        return $user;
    }

    public static function verifyLoginPassword($mobile, $password)
    {
        if (empty($mobile) || empty($password)) {
            self::$errorCode = ERROR_LOGIN_MOBILE_OR_PASSWORD_EMPTY;
            return false;
        }
        $user = \app\models\User::findFirst([
            'conditions' => 'mobile=?0 status=' . \app\models\User::STATUS_NORMAL,
            'column' => 'id,open_id,password,nickname,icon,last_login_token,gender,age',
            'bind' => [
                $mobile
            ],
        ]);
//        $user = \app\models\User::modelFind(['mobile' => $mobile], 'id,open_id,password,nickname,icon,last_login_token');
        if (!$user) {
            self::$errorCode = ERROR_MOBILE_NUMBER_NOT_EXISTS;
            return false;
        }
        if (!$user->getSecurity()->checkHash($password, $user->password)) {
            self::$errorCode = ERROR_LOGIN_PASSWORD_ERROR;
            return false;
        }
        return $user;
    }

    /**
     * @param $user \app\models\User
     * @param $request Request
     */
    public static function userLoginLog(&$user, &$request)
    {
        $collection = new Collection(Table::MONGO_USER_LOGIN_LOG);
        $data = [
            'uid' => $user->open_id,
            'ip' => $user->last_login_ip,
            'agent' => substr($request->getUserAgent(), 0, 255),
            'created_at' => time()
        ];
        $appId = $request->getPost('app_id');
        if ($appId) {
            $data['app'] = $appId;
        }
        return $collection->insertOne($data);
    }

    public static function verifyRegisterCaptcha(&$captcha, &$mobile)
    {
        return true;
    }

    /**
     * @param $request \Phalcon\Http\Request|\Phalcon\Http\RequestInterface
     */
    public static function register(&$request)
    {
        $user = new \app\models\User($request->getPost());
        $mobile =  $request->getPost('mobile');
        $captcha = $request->getPost('captcha');
        if (!self::verifyRegisterCaptcha($captcha, $mobile)) {
            self::$errorCode = ERROR_CAPTCHA_INVALID;
            return false;
        }
        if (!$user->create()) {
            self::$errorCode = $user::$errorCode;
            return false;
        }
        return $user;
    }

    public static function logout($token)
    {
        if (empty($token)) {
            self::$errorCode = ERROR_INVALID_PARAM;
            return false;
        }
        $cache = Application::$app->getCache();
        $flag = $cache->delete($token);
        if (!$flag) {
            self::$errorCode = ERROR_INVALID_PARAM;
            return false;
        }
        return true;
    }

    /**
     * @param $request Request
     */
    public function update(&$request)
    {
        $data = [];
        $nickname = $request->getPost('nickname');
        if (!empty($nickname)) {
            $data['nickname'] = html_entity_decode($nickname);
        }
        $age = $request->getPost('age');
        if (!empty($age)) {
            $data['age'] = (int)$age;
        }
        $password = $request->getPost('password');
        $oldPassword = $request->getPost('old_password');
        $user = null;
        if ($password) {
            $user = $this->updateLoginUserPassword($password, $oldPassword);
            if (!$user) {
                return false;
            }
            $password = Application::$app->security->hash($password,2);
            $data['password'] = $password;
        }
        if (!$request->hasFiles()) {
            if (empty($data)) {
                self::$errorCode = ERROR_REQUEST_DATA_EMPTY;
                return false;
            }
            $user = Application::$app->user->user;
            if (!\app\models\User::modelUpdate($user->getSource(), ['open_id' => $user->open_id], $data)) {
                Application::$app->logger->error(json_encode(\app\models\User::getErrorInfo()));
                self::$errorCode = ERROR_OPERATION_FAILED;
                return false;
            }
            return true;
        }
        if (!$user) {
            $user = Application::$app->user->user;
        }
        return $this->updateUserIcon($request, $user, $data);

    }

    /**
     * @param $request Request
     * @param $user \app\models\User
     * @param $data []
     */
    public function updateUserIcon(&$request, &$user, &$data)
    {
        $files = $request->getUploadedFiles();
        if (count($files) != 1) {
            self::$errorCode = ERROR_UPLOAD_FILE_NUMBER_ERROR;
            return false;
        }
        $file = $files[0];
        if ($file->getError() !== 0) {
            self::$errorCode = $file->getError();
            return false;
        }
        $realType = $file->getRealType(); //这个函数获取的事真实的类型，包含了 mime信息的
        $type = explode('/', $realType);
        if (!isset($type[1])) {
            self::$errorCode = ERROR_UPLOAD_FILE_FAILED;
            return false;
        }
        if (!in_array($type[1], ['jpeg', 'jpg', 'png'])) {
            self::$errorCode = ERROR_UPLOAD_FILE_TYPE_ERROR;
            return false;
        }
        if ($file->getSize() > 2097152) {
            self::$errorCode = ERROR_UPLOAD_FILE_SIZE_ERROR;
            return false;
        }
        $filename = Application::$app->genRandomString(10) . '.' . $type[1];

    }

    public function updateLoginUserPassword($password, $oldPassword)
    {
        if (empty($oldPassword)) {
            self::$errorCode = ERROR_OLD_PASSWORD_REQUIRED;
            return false;
        }
        $user = Application::$app->user->user;
        $user = \app\models\User::findFirst(['condition' => 'open_id=' . $user->open_id, 'limit' => 1, 'columns' => 'open_id,nickname,icon,age,password']);
        if (!$user) {
            self::$errorCode = ERROR_USER_NOT_EXISTS;
            return false;
        }
        //验证老密码 是否正确
        if (!Application::$app->security->checkHash($oldPassword,  $user->password)) {
            self::$errorCode = ERROR_PASSWORD_ERROR;
            return false;
        }
        return $user;
    }
}